package com.vegetable.common.utils;

import com.vegetable.modules.entity.stock.CostWeightChangeSource;
import com.vegetable.modules.entity.stock.Stock;

import java.math.BigDecimal;
import java.util.List;

/**
 * <p>
 * 成本变化工具类
 * </p>
 *
 * @author wangruijie
 * @since 2024-03-21
 */
public class CostChangeUtils {

    /**
     * 计算成本变化百分比
     * @param beforeCost 变化前成本
     * @param afterCost 变化后成本
     * @return 成本变化百分比
     */
    public static BigDecimal calculateChangePercentage(BigDecimal beforeCost, BigDecimal afterCost) {
        if (beforeCost == null || afterCost == null || beforeCost.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        
        return afterCost.subtract(beforeCost)
            .multiply(new BigDecimal("100"))
            .divide(beforeCost, 2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 计算总成本变化金额
     * @param changes 成本变化列表
     * @return 总成本变化金额
     */
    public static BigDecimal calculateTotalChangeAmount(List<CostWeightChangeSource> changes) {
        if (changes == null || changes.isEmpty()) {
            return BigDecimal.ZERO;
        }
        
        return changes.stream()
            .map(CostWeightChangeSource::getChangeAmount)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 计算加权平均成本
     * @param stocks 库存列表
     * @return 加权平均成本
     */
    public static BigDecimal calculateWeightedAverageCost(List<Stock> stocks) {
        if (stocks == null || stocks.isEmpty()) {
            return BigDecimal.ZERO;
        }
        
        BigDecimal totalWeight = BigDecimal.ZERO;
        BigDecimal totalCost = BigDecimal.ZERO;
        
        for (Stock stock : stocks) {
            if (stock.getWeight() != null && stock.getCostWeight() != null) {
                BigDecimal cost = stock.getWeight().multiply(stock.getCostWeight());
                totalCost = totalCost.add(cost);
                totalWeight = totalWeight.add(stock.getWeight());
            }
        }
        
        if (totalWeight.compareTo(BigDecimal.ZERO) != 0) {
            return totalCost.divide(totalWeight, 6, BigDecimal.ROUND_HALF_UP);
        }
        
        return BigDecimal.ZERO;
    }

    /**
     * 判断是否为显著变化
     * @param changeAmount 变化金额
     * @param threshold 阈值
     * @return 是否为显著变化
     */
    public static boolean isSignificantChange(BigDecimal changeAmount, BigDecimal threshold) {
        if (changeAmount == null || threshold == null) {
            return false;
        }
        
        return changeAmount.abs().compareTo(threshold.abs()) >= 0;
    }
}